package cn.wolfcode.business.service.impl;

import java.util.Date;
import java.util.List;

import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.business.utils.RegexUtils;
import cn.wolfcode.business.utils.VehiclePlateNoUtil;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.BusAppointmentMapper;
import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.service.IBusAppointmentService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 养修信息预约Service业务层处理
 *
 * @author wolfcode
 * @date 2025-03-31
 */
@Service
public class BusAppointmentServiceImpl implements IBusAppointmentService {
    @Autowired
    private BusAppointmentMapper busAppointmentMapper;

    @Autowired
    private IBusStatementService statementService;

    /**
     * 查询养修信息预约
     *
     * @param id 养修信息预约主键
     * @return 养修信息预约
     */
    @Override
    public BusAppointment selectBusAppointmentById(Long id) {
        return busAppointmentMapper.selectBusAppointmentById(id);
    }

    /**
     * 查询养修信息预约列表
     *
     * @param busAppointment 养修信息预约
     * @return 养修信息预约
     */
    @Override
    public List<BusAppointment> selectBusAppointmentList(BusAppointment busAppointment) {
        return busAppointmentMapper.selectBusAppointmentList(busAppointment);
    }

    /**
     * 新增养修信息预约
     *
     * @param busAppointment 养修信息预约
     * @return 结果
     */
    @Override
    public int insertBusAppointment(BusAppointment busAppointment) {
        //验证参数合法性
        if (StringUtils.isNull(busAppointment)) {
            throw new RuntimeException("非法参数");
        }
        if (
                StringUtils.isNull(busAppointment.getCustomerPhone())//获取客户联系方式
                        || StringUtils.isNull(busAppointment.getAppointmentTime())//预约时间
                        || StringUtils.isNull(busAppointment.getLicensePlate())//车牌号码
                        || StringUtils.isNull(busAppointment.getCarSeries())//汽车类型
                        || StringUtils.isNull(busAppointment.getServiceType())//服务类型
        ) {
            throw new RuntimeException("非法参数");
        }

        //验证手机号合法性
        if (!RegexUtils.isChinaPhoneLegal(busAppointment.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式有误");
        }

        //验证车牌号是否合法  返回的是枚举类型
        //通过上面判断不为空的时候再拿下来进行对比，如果对比出结果，则车牌号有效，若对比失败，则返回空 即车牌号非法
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo = VehiclePlateNoUtil.getVehiclePlateNo(busAppointment.getLicensePlate());
        if (vehiclePlateNo == null) {
            throw new RuntimeException("车牌号码格式有误");
        }

        //验证时间合法性
        Date nowDate = DateUtils.getNowDate();
        if (busAppointment.getAppointmentTime().before(nowDate)) {
            throw new RuntimeException("预约时间不合法");
        }

        //为了系统安全性 一般前台直接传递的对象是不可以直接使用的，因为有一些默认值的存在
        //防止被携带的数据恶意修改导致系统出现异常，这时候一般都需要给对象中的数据进行一些修改，这里主要是指status
        busAppointment.setStatus(BusAppointment.STATUS_BOOKING);
        busAppointment.setCreateTime(DateUtils.getNowDate());
        return busAppointmentMapper.insertBusAppointment(busAppointment);
    }

    /**
     * 修改养修信息预约
     *
     * @param busAppointment 养修信息预约
     * @return 结果
     */
    @Override
    public int updateBusAppointment(BusAppointment busAppointment) {//验证参数合法性
        if (StringUtils.isNull(busAppointment)) {
            throw new RuntimeException("非法参数");
        }
        if (
                StringUtils.isNull(busAppointment.getCustomerPhone())//获取客户联系方式
                        || StringUtils.isNull(busAppointment.getAppointmentTime())//预约时间
                        || StringUtils.isNull(busAppointment.getLicensePlate())//车牌号码
                        || StringUtils.isNull(busAppointment.getCarSeries())//汽车类型
                        || StringUtils.isNull(busAppointment.getServiceType())//服务类型
        ) {
            throw new RuntimeException("非法参数");
        }

        //验证手机号合法性
        if (!RegexUtils.isChinaPhoneLegal(busAppointment.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式有误");
        }

        //验证车牌号是否合法  返回的是枚举类型
        //通过上面判断不为空的时候再拿下来进行对比，如果对比出结果，则车牌号有效，若对比失败，则返回空 即车牌号非法
        VehiclePlateNoUtil.VehiclePlateNoEnum vehiclePlateNo = VehiclePlateNoUtil.getVehiclePlateNo(busAppointment.getLicensePlate());
        if (vehiclePlateNo == null) {
            throw new RuntimeException("车牌号码格式有误");
        }

        //验证时间合法性
        Date nowDate = DateUtils.getNowDate();
        if (busAppointment.getAppointmentTime().before(nowDate)) {
            throw new RuntimeException("预约时间不合法");
        }

        //只有状态为预约中的才可以进行编辑
        //前台传递的数据很可能将一些重要的参数篡改过，所以不能直接进行使用
        //查出原始对象，数据为正确的
        BusAppointment oldObj = busAppointmentMapper.selectBusAppointmentById(busAppointment.getId());
        if (!oldObj.getStatus().equals(BusAppointment.STATUS_BOOKING)) {
            throw new RuntimeException("只有状态为预约中的才可以进行编辑");
        }
        //为了防止恶意修改，可以将状态重新赋值
        busAppointment.setStatus(oldObj.getStatus());
        return busAppointmentMapper.updateBusAppointment(busAppointment);
    }

    /**
     * 批量删除养修信息预约
     *
     * @param ids 需要删除的养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteBusAppointmentByIds(Long[] ids) {
        if (ids == null || ids.length <= 0) {
            throw new RuntimeException("非法参数");
        }
        for (Long id : ids) {
            BusAppointment oldObj = this.selectBusAppointmentById(id);
            if (oldObj == null) {
                throw new RuntimeException("非法参数");
            }
            if(!BusAppointment.STATUS_BOOKING.equals(oldObj.getStatus())){
                throw new RuntimeException("非预约中的记录无法删除");
            }
        }
        return busAppointmentMapper.deleteBusAppointmentByIds(ids);

        //优化  批量删除
//        boolean flag = true;
//        List<BusAppointment> busAppointments = busAppointmentMapper.selectBusAppointmentListBatch(ids);
//        if(busAppointments == null || busAppointments.size() <= 0){
//            throw new RuntimeException("非法参数");
//        }
//        for (BusAppointment busAppointment : busAppointments) {
//            flag = flag && BusAppointment.STATUS_BOOKING.equals(busAppointment.getStatus());
//        }
//        if(!flag){
//            throw new RuntimeException("非预约中的记录无法删除");
//        }
//        return busAppointmentMapper.deleteBusAppointmentByIds(ids);
    }

    /**
     * 删除养修信息预约信息
     *
     * @param id 养修信息预约主键
     * @return 结果
     */
    @Override
    public int deleteBusAppointmentById(Long id) {
        return busAppointmentMapper.deleteBusAppointmentById(id);
    }

    /**
     * 到店功能
     *
     * @param id 养修信息预约主键
     * @return 结果
     */
    @Override
    public int arrived(Long id) {
        //参数合理化验证
        if (id == null) {
            throw new RuntimeException("非法参数");
        }
        //this调本类获取BusAppointment对象 尽量调service不要调mapper
        BusAppointment oldObj = this.selectBusAppointmentById(id);
        if (oldObj == null) {
            throw new RuntimeException("非法参数");
        }

        //必须是预约中才能进行到店操作
        if (!BusAppointment.STATUS_BOOKING.equals(oldObj.getStatus())) {
            throw new RuntimeException("必须处于预约记录中才能进行到店操作");
        }
        //进行到店日期更新和预约状态更新
        return busAppointmentMapper.changeStatusAndArrivedTimeById(new Date(), BusAppointment.STATUS_ARRIVED, id);
    }

    /*取消功能*/
    @Override
    public int cancel(Long id) {
        //参数合理化验证
        if (id == null) {
            throw new RuntimeException("非法参数");
        }
        //this调本类获取BusAppointment对象 尽量调service不要调mapper
        BusAppointment oldObj = this.selectBusAppointmentById(id);
        if (oldObj == null) {
            throw new RuntimeException("非法参数");
        }

        //必须是预约中才能进行取消操作
        if (!BusAppointment.STATUS_BOOKING.equals(oldObj.getStatus())) {
            throw new RuntimeException("必须处于预约记录中才能进行取消操作");
        }
        return busAppointmentMapper.changeStatusByAppointmentById(id, BusAppointment.STATUS_USER_CANCELLED);
    }

    /*通过预约单id创建或查看结算单*/
    @Override
    @Transactional
    public Long createOrSelectStatement(Long appointmentId) {
        //合理化校验
        if(appointmentId == null){
            System.out.println("appointmentId为空");
            throw new RuntimeException("非法参数");
        }
        //根据预约单id查询预约单对象
        BusAppointment busAppointment = this.selectBusAppointmentById(appointmentId);
        if(busAppointment == null) {
            System.out.println("busAppointment为空");
            throw new RuntimeException("非法参数");
        }
        //判断预约单状态
        if(BusAppointment.STATUS_BOOKING.equals(busAppointment.getStatus())
                || BusAppointment.STATUS_USER_CANCELLED.equals(busAppointment.getStatus())
                || BusAppointment.STATUS_TIMEOUT_CANCELLED.equals(busAppointment.getStatus())){
            throw new RuntimeException("预约单处于预约中、用户取消、超时取消则不允许生成或查找结算单");
        }

        //根据预约单id查询结算单对象
        /*BusStatement busStatement = statementService.selectBusStatementById(appointmentId);*/
        BusStatement busStatement = statementService.selectByAppointmentId(appointmentId);
        //若没有查询到结算单，则需要创建一个结算单
        if(busStatement == null){
            busStatement = new BusStatement();
            //客户姓名
            busStatement.setCustomerName(busAppointment.getWxUserId() == null ? "客服录入":"用户微信名");
            //联系方式
            busStatement.setCustomerPhone(busAppointment.getCustomerPhone());
            //到店时间
            busStatement.setActualArrivalTime(busAppointment.getActualArrivalTime());
            //车牌号码
            busStatement.setLicensePlate(busAppointment.getLicensePlate());
            //汽车类型
            busStatement.setCarSeries(busAppointment.getCarSeries());
            //服务类型
            busStatement.setServiceType(busAppointment.getServiceType());
            //预约单id
            busStatement.setAppointmentId(busAppointment.getId());
            //支付状态
            busStatement.setStatus(BusStatement.STATUS_CONSUME);

            //执行插入操作 这样id就会回填到对象中
            statementService.insertBusStatement(busStatement);

            //更新预约单的支付状态 ==> 生成结算单
            busAppointmentMapper.changeStatusByAppointmentById(appointmentId,BusAppointment.STATUS_SETTLED);
        }
        //若存在结算单，则返回对应的结算单id
        return busStatement.getId();
    }

    /*根据预约单id修改预约单状态*/
    @Override
    public void updateStatusByAppointmentId(Long appointmentId, Integer statusPaid) {
        busAppointmentMapper.changeStatusByAppointmentById(appointmentId,statusPaid);
    }

}
